namespace SimpleWebServices.Web.UI.Html.Elements
{
    using System;
    using System.Xml;
    using System.Xml.Serialization;
    using SimpleWebServices.Data;
    using SimpleWebServices.Web.UI.Html;
    using SimpleWebServices.Web.UI.Html.Validation;

    [XmlRoot("fieldset")]
    public abstract class RadioFieldset : Fieldset, IControl
    {
        protected RadioFieldset()
        {
        }

        protected RadioFieldset(Name id, Legend legend)
        {
            this.Id = id;
            this.Name = id;
            this.Elements.Add(legend);
        }

        public bool Disabled
        {
            get;
            set;
        }

        public Name Name
        {
            get
            {
                return RadioFieldset.GetName(this);
            }

            set
            {
                RadioFieldset.SetName(this, value);
            }
        }

        public bool Suppress
        {
            get;
            set;
        }

        public int? TabIndex
        {
            get;
            set;
        }

        public string Value
        {
            get
            {
                return RadioFieldset.GetValue(this);
            }

            set
            {
                RadioFieldset.SetValue(this, value);
            }
        }

        public DataCollection ToDataCollection()
        {
            DataCollection result = new DataCollection();

            if (!this.Suppress)
            {
                result.Add(this.Name, this.Value);
            }

            return result;
        }

        public void Update(Name name, string value)
        {
            if (this.Name == name)
            {
                this.Value = value;
            }
        }

        private static string GetName(IInnerElements obj)
        {
            string result = null;

            if (null != obj)
            {
                foreach (IElement element in obj.Elements)
                {
                    result = GetName(element as IInnerElements);
                    if (null != result)
                    {
                        break;
                    }

                    RadioInput input = element as RadioInput;
                    if (null != input)
                    {
                        result = input.Name;
                        break;
                    }
                }
            }

            return result;
        }

        private static string SetName(IInnerElements obj, string name)
        {
            string result = null;

            if (null != obj)
            {
                foreach (IElement element in obj.Elements)
                {
                    SetName(element as IInnerElements, name);
                    RadioInput input = element as RadioInput;
                    if (null != input)
                    {
                        input.Name = name;
                    }
                }
            }

            return result;
        }

        private static string GetValue(IInnerElements obj)
        {
            string result = null;

            if (null != obj)
            {
                foreach (IElement element in obj.Elements)
                {
                    result = GetValue(element as IInnerElements);
                    if (null != result)
                    {
                        break;
                    }

                    RadioInput input = element as RadioInput;
                    if (null != input && input.Checked)
                    {
                        result = input.Value;
                        break;
                    }
                }
            }

            return result;
        }

        private static string SetValue(IInnerElements obj, string value)
        {
            string result = null;

            if (null != obj)
            {
                foreach (IElement element in obj.Elements)
                {
                    SetValue(element as IInnerElements, value);
                    RadioInput input = element as RadioInput;
                    if (null != input)
                    {
                        input.Checked = 0 == string.Compare(value, input.Value, StringComparison.OrdinalIgnoreCase) ? true : false;
                    }
                }
            }

            return result;
        }
    }
}